<!--
  Custom Materials Demo Component

  This demo shows how to create and use custom materials in CesiumJS.
  It demonstrates different ways to style entities with custom materials
  including image-based materials, color materials, and custom shaders.

  Features:
    - Color materials
    - Image materials
    - Grid materials
    - Stripe materials
    - Custom shader materials
-->

<template>
  <div class="demo-container">
    <BaseCesiumViewer 
      ref="cesiumViewer" 
      
      @viewer-ready="onViewerReady"
    />
    <div class="control-panel">
      <h3>Material Controls</h3>
      
      <div class="control-group">
        <h4>Material Selection</h4>
        <ControlItem
          type="select"
          label="Active Material"
          :value="selectedMaterial"
          @update:value="selectedMaterial = $event"
        >
          <option value="color">Color Material</option>
          <option value="image">Image Material</option>
          <option value="grid">Grid Material</option>
          <option value="stripe">Stripe Material</option>
          <option value="checkerboard">Checkerboard Material</option>
        </ControlItem>
      </div>
      
      <div class="control-group" v-if="selectedMaterial === 'color'">
        <h4>Color Material</h4>
        <ControlItem
          type="range"
          label="Red: {{ Math.round(colorMaterial.red * 255) }}"
          :value="colorMaterial.red"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="colorMaterial.red = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Green: {{ Math.round(colorMaterial.green * 255) }}"
          :value="colorMaterial.green"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="colorMaterial.green = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Blue: {{ Math.round(colorMaterial.blue * 255) }}"
          :value="colorMaterial.blue"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="colorMaterial.blue = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Alpha: {{ colorMaterial.alpha.toFixed(2) }}"
          :value="colorMaterial.alpha"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="colorMaterial.alpha = $event"
          @input="updateMaterials"
        />
      </div>
      
      <div class="control-group" v-if="selectedMaterial === 'image'">
        <h4>Image Material</h4>
        <ControlItem
          type="range"
          label="Alpha: {{ imageMaterial.alpha.toFixed(2) }}"
          :value="imageMaterial.alpha"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="imageMaterial.alpha = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Repeat X: {{ imageMaterial.repeatX }}"
          :value="imageMaterial.repeatX"
          :min="1"
          :max="10"
          :step="0.1"
          @update:value="imageMaterial.repeatX = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Repeat Y: {{ imageMaterial.repeatY }}"
          :value="imageMaterial.repeatY"
          :min="1"
          :max="10"
          :step="0.1"
          @update:value="imageMaterial.repeatY = $event"
          @input="updateMaterials"
        />
      </div>
      
      <div class="control-group" v-if="selectedMaterial === 'grid'">
        <h4>Grid Material</h4>
        <ControlItem
          type="range"
          label="Line Count X: {{ gridMaterial.lineCountX }}"
          :value="gridMaterial.lineCountX"
          :min="1"
          :max="20"
          :step="1"
          @update:value="gridMaterial.lineCountX = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Line Count Y: {{ gridMaterial.lineCountY }}"
          :value="gridMaterial.lineCountY"
          :min="1"
          :max="20"
          :step="1"
          @update:value="gridMaterial.lineCountY = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Line Thickness X: {{ gridMaterial.lineThicknessX }}"
          :value="gridMaterial.lineThicknessX"
          :min="1"
          :max="10"
          :step="0.1"
          @update:value="gridMaterial.lineThicknessX = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Line Thickness Y: {{ gridMaterial.lineThicknessY }}"
          :value="gridMaterial.lineThicknessY"
          :min="1"
          :max="10"
          :step="0.1"
          @update:value="gridMaterial.lineThicknessY = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Cell Alpha: {{ gridMaterial.cellAlpha.toFixed(2) }}"
          :value="gridMaterial.cellAlpha"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="gridMaterial.cellAlpha = $event"
          @input="updateMaterials"
        />
      </div>
      
      <div class="control-group" v-if="selectedMaterial === 'stripe'">
        <h4>Stripe Material</h4>
        <ControlItem
          type="range"
          label="Repeat: {{ stripeMaterial.repeat }}"
          :value="stripeMaterial.repeat"
          :min="1"
          :max="20"
          :step="0.1"
          @update:value="stripeMaterial.repeat = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Offset: {{ stripeMaterial.offset.toFixed(2) }}"
          :value="stripeMaterial.offset"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="stripeMaterial.offset = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="select"
          label="Orientation"
          :value="stripeMaterial.orientation"
          @update:value="stripeMaterial.orientation = $event"
          @change="updateMaterials"
        >
          <option value="HORIZONTAL">Horizontal</option>
          <option value="VERTICAL">Vertical</option>
        </ControlItem>
      </div>
      
      <div class="control-group" v-if="selectedMaterial === 'checkerboard'">
        <h4>Checkerboard Material</h4>
        <ControlItem
          type="range"
          label="Repeat X: {{ checkerboardMaterial.repeatX }}"
          :value="checkerboardMaterial.repeatX"
          :min="1"
          :max="20"
          :step="0.1"
          @update:value="checkerboardMaterial.repeatX = $event"
          @input="updateMaterials"
        />
        
        <ControlItem
          type="range"
          label="Repeat Y: {{ checkerboardMaterial.repeatY }}"
          :value="checkerboardMaterial.repeatY"
          :min="1"
          :max="20"
          :step="0.1"
          @update:value="checkerboardMaterial.repeatY = $event"
          @input="updateMaterials"
        />
      </div>
      
      <button @click="resetToDefaults" class="reset-button">Reset to Defaults</button>
    </div>
  </div>
</template>

<script>
import { ref, reactive } from 'vue';
import BaseCesiumViewer from '../core/BaseCesiumViewer.vue';
import ControlItem from '../components/ControlItem.vue';
import { setViewRectangle } from '../utils';

export default {
  name: 'CustomMaterialsDemo',
  components: {
    BaseCesiumViewer,
    ControlItem
  },
  setup() {
    // References to Cesium entities
    let colorEntity, imageEntity, gridEntity, stripeEntity, checkerboardEntity;
    let viewer, Cesium;
    
    // Reactive settings for UI controls
    const selectedMaterial = ref('color');
    
    const colorMaterial = reactive({
      red: 1.0,
      green: 0.0,
      blue: 0.0,
      alpha: 0.5
    });
    
    const imageMaterial = reactive({
      alpha: 0.7,
      repeatX: 2.0,
      repeatY: 2.0
    });
    
    const gridMaterial = reactive({
      lineCountX: 8,
      lineCountY: 8,
      lineThicknessX: 2.0,
      lineThicknessY: 2.0,
      cellAlpha: 0.3
    });
    
    const stripeMaterial = reactive({
      repeat: 5.0,
      offset: 0.0,
      orientation: 'VERTICAL'
    });
    
    const checkerboardMaterial = reactive({
      repeatX: 5.0,
      repeatY: 5.0
    });

    const onViewerReady = (payload) => {
      // Check if payload and viewer are valid
      if (!payload || !payload.viewer) {
        console.error('Viewer is not ready or payload is invalid');
        return;
      }
      
      viewer = payload.viewer;
      Cesium = payload.Cesium;
      
      // Create polygon with color material
      colorEntity = viewer.entities.add({
        name: 'Color Material',
        polygon: {
          hierarchy: Cesium.Cartesian3.fromDegreesArray([
            -100.0, 30.0,
            -90.0, 30.0,
            -90.0, 40.0,
            -100.0, 40.0
          ]),
          material: Cesium.Color.RED.withAlpha(0.5)
        }
      });

      // Create polygon with image material
      imageEntity = viewer.entities.add({
        name: 'Image Material',
        polygon: {
          hierarchy: Cesium.Cartesian3.fromDegreesArray([
            -110.0, 30.0,
            -100.0, 30.0,
            -100.0, 40.0,
            -110.0, 40.0
          ]),
          material: new Cesium.ImageMaterialProperty({
            image: './img/logo.png',
            color: Cesium.Color.WHITE.withAlpha(0.7),
            repeat: new Cesium.Cartesian2(2.0, 2.0)
          })
        }
      });

      // Create polygon with grid material
      gridEntity = viewer.entities.add({
        name: 'Grid Material',
        polygon: {
          hierarchy: Cesium.Cartesian3.fromDegreesArray([
            -90.0, 30.0,
            -80.0, 30.0,
            -80.0, 40.0,
            -90.0, 40.0
          ]),
          material: new Cesium.GridMaterialProperty({
            color: Cesium.Color.YELLOW,
            cellAlpha: 0.3,
            lineCount: new Cesium.Cartesian2(8, 8),
            lineThickness: new Cesium.Cartesian2(2.0, 2.0)
          })
        }
      });

      // Create polygon with stripe material
      stripeEntity = viewer.entities.add({
        name: 'Stripe Material',
        polygon: {
          hierarchy: Cesium.Cartesian3.fromDegreesArray([
            -80.0, 30.0,
            -70.0, 30.0,
            -70.0, 40.0,
            -80.0, 40.0
          ]),
          material: new Cesium.StripeMaterialProperty({
            evenColor: Cesium.Color.WHITE,
            oddColor: Cesium.Color.BLUE,
            repeat: 5.0,
            offset: 0.0,
            orientation: Cesium.StripeOrientation.VERTICAL
          })
        }
      });

      // Create ellipse with checkerboard material
      checkerboardEntity = viewer.entities.add({
        name: 'Checkerboard Material',
        position: Cesium.Cartesian3.fromDegrees(-105.0, 35.0),
        ellipse: {
          semiMinorAxis: 200000.0,
          semiMajorAxis: 300000.0,
          material: new Cesium.CheckerboardMaterialProperty({
            evenColor: Cesium.Color.WHITE,
            oddColor: Cesium.Color.BLACK,
            repeat: new Cesium.Cartesian2(5.0, 5.0)
          })
        }
      });

      // Set initial view to show all entities
      setViewRectangle(viewer, {
        west: -115,
        south: 25,
        east: -65,
        north: 45
      });
    };
    
    // Update materials based on UI controls
    const updateMaterials = () => {
      switch (selectedMaterial.value) {
        case 'color':
          if (colorEntity && colorEntity.polygon) {
            colorEntity.polygon.material = new Cesium.Color(
              colorMaterial.red,
              colorMaterial.green,
              colorMaterial.blue,
              colorMaterial.alpha
            );
          }
          break;
          
        case 'image':
          if (imageEntity && imageEntity.polygon) {
            imageEntity.polygon.material = new Cesium.ImageMaterialProperty({
              image: './img/logo.png',
              color: Cesium.Color.WHITE.withAlpha(imageMaterial.alpha),
              repeat: new Cesium.Cartesian2(imageMaterial.repeatX, imageMaterial.repeatY)
            });
          }
          break;
          
        case 'grid':
          if (gridEntity && gridEntity.polygon) {
            gridEntity.polygon.material = new Cesium.GridMaterialProperty({
              color: Cesium.Color.YELLOW,
              cellAlpha: gridMaterial.cellAlpha,
              lineCount: new Cesium.Cartesian2(gridMaterial.lineCountX, gridMaterial.lineCountY),
              lineThickness: new Cesium.Cartesian2(gridMaterial.lineThicknessX, gridMaterial.lineThicknessY)
            });
          }
          break;
          
        case 'stripe':
          if (stripeEntity && stripeEntity.polygon) {
            stripeEntity.polygon.material = new Cesium.StripeMaterialProperty({
              evenColor: Cesium.Color.WHITE,
              oddColor: Cesium.Color.BLUE,
              repeat: stripeMaterial.repeat,
              offset: stripeMaterial.offset,
              orientation: stripeMaterial.orientation === 'HORIZONTAL' 
                ? Cesium.StripeOrientation.HORIZONTAL 
                : Cesium.StripeOrientation.VERTICAL
            });
          }
          break;
          
        case 'checkerboard':
          if (checkerboardEntity && checkerboardEntity.ellipse) {
            checkerboardEntity.ellipse.material = new Cesium.CheckerboardMaterialProperty({
              evenColor: Cesium.Color.WHITE,
              oddColor: Cesium.Color.BLACK,
              repeat: new Cesium.Cartesian2(checkerboardMaterial.repeatX, checkerboardMaterial.repeatY)
            });
          }
          break;
      }
    };
    
    // Reset to defaults based on the selected material
    const resetToDefaults = () => {
      switch (selectedMaterial.value) {
        case 'color':
          colorMaterial.red = 1.0;
          colorMaterial.green = 0.0;
          colorMaterial.blue = 0.0;
          colorMaterial.alpha = 0.5;
          break;
          
        case 'image':
          imageMaterial.alpha = 0.7;
          imageMaterial.repeatX = 2.0;
          imageMaterial.repeatY = 2.0;
          break;
          
        case 'grid':
          gridMaterial.lineCountX = 8;
          gridMaterial.lineCountY = 8;
          gridMaterial.lineThicknessX = 2.0;
          gridMaterial.lineThicknessY = 2.0;
          gridMaterial.cellAlpha = 0.3;
          break;
          
        case 'stripe':
          stripeMaterial.repeat = 5.0;
          stripeMaterial.offset = 0.0;
          stripeMaterial.orientation = 'VERTICAL';
          break;
          
        case 'checkerboard':
          checkerboardMaterial.repeatX = 5.0;
          checkerboardMaterial.repeatY = 5.0;
          break;
      }
      updateMaterials();
    };

    return {
      selectedMaterial,
      colorMaterial,
      imageMaterial,
      gridMaterial,
      stripeMaterial,
      checkerboardMaterial,
      Math,
      onViewerReady,
      updateMaterials,
      resetToDefaults
    };
  }
};
</script>

<style scoped>
.demo-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.control-panel {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 300px;
  max-height: calc(100% - 40px);
  background: rgba(40, 40, 40, 0.8);
  color: white;
  padding: 15px;
  border-radius: 5px;
  overflow-y: auto;
  z-index: 100;
  backdrop-filter: blur(5px);
}

.control-group {
  margin-bottom: 20px;
}

.control-group h4 {
  margin-top: 0;
  margin-bottom: 10px;
  border-bottom: 1px solid #666;
  padding-bottom: 5px;
}

.reset-button {
  width: 100%;
  padding: 10px;
  background: #2196f3;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  font-weight: bold;
}

.reset-button:hover {
  background: #1976d2;
}
</style>